package controllers

import (
	"commerce/cache"
	"commerce/captcha"
	"commerce/common"
	"commerce/data"
	"commerce/model"
	"commerce/utils"
	"commerce/vo"
	"crypto/md5"
	"database/sql"
	"fmt"
	"github.com/go-sql-driver/mysql"
	"html/template"
	"net/http"
	"path/filepath"
	"strconv"
	"strings"
)

var sALT = "YOU be good, man!"
var captchaErr error = nil

const (
	dx = 100
	dy = 33
)

func init() {

	common.Templates["admin"] = template.Must(template.ParseFiles(filepath.Join(common.CurDir, "views/templates/admin.html")))
	common.Templates["admin_edit"] = template.Must(template.ParseFiles(filepath.Join(common.CurDir, "views/templates/admin_edit.html")))
}

func MsgToLoginPageHandler(w http.ResponseWriter, r *http.Request) {
	common.Templates["msg_to_login"].Execute(w, nil)
}

func MsgToHomePageHandler(w http.ResponseWriter, r *http.Request) {
	common.Templates["msg_to_homepage"].Execute(w, nil)
}

func RootPageHandler(w http.ResponseWriter, r *http.Request) {

	_, err := common.ParseJwtUser(r)

	if err != nil {
		http.Redirect(w, r, "/login.html", http.StatusFound)
		return
	}
	http.Redirect(w, r, "/commerce/api/v2/index", http.StatusFound)
}

func LoginPageHandler(w http.ResponseWriter, r *http.Request) {
	common.Templates["login"].Execute(w, nil)
}

func LoginHandler(w http.ResponseWriter, r *http.Request) {

	r.ParseForm()
	username := r.PostFormValue("username")
	password := r.PostFormValue("password")
	captcha := r.PostFormValue("captcha")

	var loginVo = vo.LoginVo{Username: username, Password: password, Captcha: captcha}
	if len(username) == 0 || strings.TrimSpace(username) == "" {
		loginVo.Msg = "请输入用户名"
		//common.Templates["login"].Execute(w, "请输入用户名")
		common.Templates["login"].Execute(w, loginVo)
		return
	}
	if captchaErr == nil {

		if len(strings.TrimSpace(captcha)) != 4 {
			//common.Templates["login"].Execute(w, "请输入验证码")
			loginVo.Msg = "请输入验证码"
			common.Templates["login"].Execute(w, loginVo)
			return
		}
		cookie, err := r.Cookie(common.CaptchaCookie)
		if err != nil {
			loginVo.Msg = "验证码验证错误"
			common.Templates["login"].Execute(w, loginVo)
			return
		}
		captchaKey := strings.ToLower(common.CaptchaPrefix + cookie.Value + captcha)
		flag, _ := cache.Get(captchaKey)
		if flag != "1" {
			loginVo.Msg = "验证码错误"
			common.Templates["login"].Execute(w, loginVo)
			return
		}
		cache.Delete(captchaKey)
		http.SetCookie(w, &http.Cookie{Name: common.CaptchaCookie, MaxAge: -1, Domain: common.AppConfig.CookieDomain})
	}
	sum := md5.Sum([]byte(sALT + password))
	user, err := data.GetAdminByUp(username, fmt.Sprintf("%x", sum[:]))
	if err != nil {
		if err == sql.ErrNoRows {
			//common.Templates["login"].Execute(w, "用户名或密码错误！")
			loginVo.Msg = "用户名或密码错误！"
			common.Templates["login"].Execute(w, loginVo)
			return
		}
		//common.Templates["login"].Execute(w, err.Error())
		loginVo.Msg = err.Error()
		common.Templates["login"].Execute(w, loginVo)
		return
	}
	token, err := common.GenerateJWT(*user)
	if err != nil {
		//common.Templates["login"].Execute(w, err.Error())
		loginVo.Msg = err.Error()
		common.Templates["login"].Execute(w, loginVo)
		return
	}
	// 登录成功：信息放session(redis存储)
	addToSession(user.Id, w, token)

	http.Redirect(w, r, "/commerce/api/v2/index", http.StatusFound)
}

func LogoutHandler(w http.ResponseWriter, r *http.Request) {

	user, err := common.ParseJwtUser(r)
	if err != nil {
		http.Redirect(w, r, "/login.html", http.StatusFound)
		return
	}
	removeSession(w, user.Uid)
	http.Redirect(w, r, "/login.html", http.StatusFound)
}

func ListAdmin(w http.ResponseWriter, r *http.Request) {

	pageNo, err := strconv.Atoi(r.FormValue("pageNo"))
	if err != nil {
		pageNo = 1
	}
	pageSize, err := strconv.Atoi(r.FormValue("pageSize"))
	if err != nil {
		pageSize = common.PAGE_SIZE
	}

	name := strings.TrimSpace(r.FormValue("name"))

	var page, _ = data.PageAdmin(pageNo, pageSize, name)

	if page == nil {
		common.Templates["5xx"].Execute(w, nil)
		return
	}
	// 分页条件查询使用
	var qs = r.URL.RawQuery

	index := strings.Index(r.RequestURI, "&pageNo=")
	var flag bool
	// 这一步操作是点击分页来的
	if index != -1 {
		qs = r.RequestURI[:index]
		flag = true
	} else {
		// 首次点击搜索按钮查询
		flag = false
		qs = "?"
		if len(name) > 0 {
			qs += "name=" + name
		}
	}
	if flag {
		page.Url = qs
	} else {
		page.Url = r.RequestURI + qs
	}

	common.Templates["admin"].Execute(w, page)
}

func AddAdminUIHandler(w http.ResponseWriter, r *http.Request) {

	common.Templates["admin_edit"].Execute(w, nil)
}

func GetAdminHandler(w http.ResponseWriter, r *http.Request) {

	id, err := strconv.Atoi(r.FormValue("id"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	c, err := data.GetAdminById(id)
	if err != nil {
		common.Templates["5xx"].Execute(w, err)
		return
	}
	common.Templates["admin_edit"].Execute(w, c)
}

func AddOrEditAdminHandler(w http.ResponseWriter, r *http.Request) {

	var id = 0
	idVal := r.PostFormValue("id")
	if len(idVal) > 0 {
		id, _ = strconv.Atoi(idVal)
	}
	username := r.PostFormValue("username")
	password := r.PostFormValue("password")
	email := r.PostFormValue("email")
	sum := md5.Sum([]byte(sALT + password))
	g := model.User{Id: id, Username: username, Password: fmt.Sprintf("%x", sum[:]), Email: email}
	if id <= 0 {
		_, err := data.AddAdmin(g)
		if err != nil {
			switch err.(type) {
			case *mysql.MySQLError:
				common.Templates["5xx"].Execute(w, "用户名已被占用,请重新选一个!")
				return
			}
			common.Templates["5xx"].Execute(w, err)
			return
		}
	} else {
		id, _ = data.UpdateAdmin(g)
	}
	//重定向到列表
	http.Redirect(w, r, "/commerce/api/v2/admin/list", http.StatusFound)
}

func DeleteAdminHandler(w http.ResponseWriter, r *http.Request) {

	id, err := strconv.Atoi(r.FormValue("id"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	data.DeleteAdmin(id)

	//重定向到列表
	http.Redirect(w, r, "/commerce/api/v2/admin/list", http.StatusFound)
}

func SendResetPwdToUserEmail(w http.ResponseWriter, r *http.Request) {

	email := r.FormValue("email")

	npwd := utils.FilenamePrefix()
	sum := md5.Sum([]byte(sALT + npwd))
	// 更新用户密码
	err := data.UpdateAdminPwdByEmail(email, fmt.Sprintf("%x", sum[:]))
	if err != nil {
		common.Templates["5xx"].Execute(w, err)
		return
	}
	// 给用户发送邮件，告之新密码
	go utils.Send(email, "重置密码成功", "您的新密码："+npwd)
	//重定向到列表
	//http.Redirect(w, r, "/msg_to_login.html?npwd="+npwd, http.StatusFound)
	http.Redirect(w, r, "/msg_to_login.html?npwd=请登录注册邮箱查看新密码！", http.StatusFound)
}

func GetCaptcha(w http.ResponseWriter, r *http.Request) {

	captchaImage := captcha.New(dx, dy, captcha.RandLightColor())

	captchaImage.DrawNoise(captcha.CaptchaComplexLower)

	captchaImage.DrawTextNoise(captcha.CaptchaComplexLower)

	code := utils.GenerateCode(10)
	captchaText := captcha.RandText(4)
	captchaErr = cache.SetWithTTL(strings.ToLower(common.CaptchaPrefix+code+captchaText), "1", 60)
	if captchaErr != nil {
		common.Warn.Printf("err set captchaText:%s, err:%v", captchaText, captchaErr)
	}
	captchaImage.DrawText(captchaText)
	//captchaImage.Drawline(3);
	captchaImage.DrawBorder(captcha.ColorToRGB(0x17A7A7A))
	//captchaImage.DrawSineLine()
	captchaImage.DrawHollowLine()

	http.SetCookie(w, &http.Cookie{Name: common.CaptchaCookie, Value: code, MaxAge: 60, Domain: common.AppConfig.CookieDomain})
	captchaImage.SaveImage(w, captcha.ImageFormatPng)
	//w.Flush()
}

func addToSession(userId int, w http.ResponseWriter, token string) {
	cache.SetWithTTL(fmt.Sprintf("%s:%d", "USER", userId), token, common.COOKIE_MAX_AGE)
	http.SetCookie(w, &http.Cookie{Name: common.COOKIE_NAME, Value: token, MaxAge: common.COOKIE_MAX_AGE, Domain: common.AppConfig.CookieDomain})
}

func removeSession(w http.ResponseWriter, userId int) {
	cache.Delete(fmt.Sprintf("%s:%d", "USER:", userId))
	http.SetCookie(w, &http.Cookie{Name: common.COOKIE_NAME, MaxAge: -1, Domain: common.AppConfig.CookieDomain})
}
